package com.sinosoft.hydra.um.services;

import com.sinosoft.hydra.um.condition.SearchDeviceCondition;
import com.sinosoft.hydra.um.constant.BaseConstant;
import com.sinosoft.hydra.um.domain.permission.TDevice;
import cn.com.sinux.spring.exception.BusinessException;
import com.sinosoft.hydra.um.repositories.TDeviceDAO;
import cn.com.sinux.spring.utils.CodeUtils;
import cn.com.sinux.spring.utils.SpecificationHelper;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import java.util.Calendar;
import java.util.List;

/**
 * Created by Administrator on 2016/6/16.
 * 主要对设备进行处理的逻辑接口类
 */
@Service
@Transactional
public class DeviceService {

    @Autowired
    private TDeviceDAO deviceDAO;

    /**
     * 添加设备
     *
     * @param device
     */
    public TDevice addDevice(TDevice device) {
        if (StringUtils.isBlank(device.getDeviceCode())) {
            device.setDeviceCode("S" + DateFormatUtils.format(Calendar.getInstance(), "yyyyMMdd") + "-" + CodeUtils.getRandomCode(10));
        }
        if (exist(device.getDeviceCode())) {
            throw new BusinessException("#添加的设备编号已经存在");
        }
//        device.setParserDevice(BaseConstant.INTEGER_FALSE);
        return deviceDAO.save(device);
    }

    /**
     * 修改设备
     *
     * @param device
     */
    public TDevice updateDevice(TDevice device) {
        TDevice db = deviceDAO.findOne(device.getId());
        if (db == null) {
            throw new BusinessException("#修改的设备资源不存在");
        }
        if (StringUtils.isBlank(device.getDeviceCode())) {
            device.setDeviceCode("S" + DateFormatUtils.format(Calendar.getInstance(), "yyyyMMdd") + "-" + CodeUtils.getRandomCode((int)Math.pow(10, 5)));
        }
        if (!db.getDeviceCode().equals(device.getDeviceCode())
                && exist(device.getDeviceCode())) {
            throw new BusinessException("#修改的设备编号已经存在");
        }
        device.setDeviceCode(db.getDeviceCode());
        return deviceDAO.save(device);
    }

    /**
     * 删除设备
     *
     * @param ids
     */
    public List<TDevice> deleteDevices(List<String> ids) {
        List<TDevice> devices = deviceDAO.findAll(ids);
        deviceDAO.delete(devices);
        return devices;
    }

    /**
     * 判断制定code的设备是否存在。
     *
     * @param deviceCode
     * @return
     */
    private boolean exist(String deviceCode) {
        SearchDeviceCondition searchDeviceCondition = new SearchDeviceCondition();
        searchDeviceCondition.setDeviceCode(deviceCode);
        return deviceDAO.count(buildSpecification(searchDeviceCondition)) > 0;
    }

    /**
     * 获取单台设备
     *
     * @param id
     * @return
     */
    public TDevice findOneDevice(String id) {
        return StringUtils.isNotBlank(id) ? deviceDAO.findOne(id) : null;
    }

    private Specification<TDevice> buildSpecification(final SearchDeviceCondition deviceCondition) {
        Specification<TDevice> specification = SpecificationHelper.buildSpecification(new SpecificationHelper.SpecificationBuilder<TDevice>() {

            public void fillParam(Root<TDevice> root, CriteriaBuilder cb, List<Predicate> list) {
                if (StringUtils.isNotBlank(deviceCondition.getDeviceCode())) {
                    list.add(cb.equal(root.get("deviceCode").as(String.class), deviceCondition.getDeviceCode()));
                }
                if (StringUtils.isNotBlank(deviceCondition.getDeviceName())) {
                    list.add(cb.like(root.get("deviceName").as(String.class), "%" + deviceCondition.getDeviceName() + "%"));
                }
                if (deviceCondition.getParserDevice() != null) {
                    list.add(cb.equal(root.get("parserDevice").as(Integer.class), deviceCondition.getParserDevice()));
                }
                if (StringUtils.isNotBlank(deviceCondition.getManufacturer())){
                    list.add(cb.like(root.get("manufacturer").as(String.class), "%" + deviceCondition.getManufacturer() + "%"));
                }
            }
        });
        return specification;
    }

    /**
     * 查询设备
     *
     * @param deviceCondition
     * @param pageable
     * @return
     */
    public Page<TDevice> findDevices(final SearchDeviceCondition deviceCondition, Pageable pageable) {
        return deviceDAO.findAll(buildSpecification(deviceCondition), pageable);
    }
}
